package aplicationModel;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.uqbar.arena.windows.SimpleWindow;
import org.uqbar.arena.windows.Window;
import org.uqbar.arena.windows.WindowOwner;
import org.uqbar.commons.model.UserException;
import org.uqbar.commons.utils.Observable;

import view.AterrizarWindow;
import view.InformeErrorWindow;
import view.InformeExitosoWindow;
import view.InformeReservadoWindow;
import view.ListadoAsientosWindow;
import vuelo.Vuelo;
import aerolinea.TodasLasAerolineas;
import asiento.Asiento;
import asiento.EstadoAsiento;
import busqueda.Busqueda;
import excepciones.NoPuedeComprarException;
import excepciones.NoPuedeReservarException;

@Observable
public class BuscarAsientos implements Serializable{
	
	private String origen;
	private String destino;
	private String fecha;
	private List<Asiento> resultados;
	private Asiento asientoSeleccionado;
	private WindowOwner parent;
	
	public BuscarAsientos(){
		this.setResultados(new ArrayList<Asiento>());
	}
	

	// ********************************************************
	// ** Acciones
	// ********************************************************
	public void comprarAsiento()  {
		try {
			asientoSeleccionado.comprar(AterrizarWindow.usuario);
			this.openWindow(new InformeExitosoWindow(this.getParent(), this.getAsientoSeleccionado(), "comprado"));
		} catch (NoPuedeComprarException e) {
			this.openWindow(new InformeErrorWindow(this.getParent(), "compra", e.getMessage()));
		}
		this.buscar();
	}
	
	public void reservarAsiento() {
		try {
			EstadoAsiento estadoAsiento = asientoSeleccionado.reservar(AterrizarWindow.usuario);
			if(!estadoAsiento.haySobreReserva()){
				this.openWindow(new InformeExitosoWindow(this.getParent(), this.getAsientoSeleccionado(), "reservado"));
			}else{
				this.openWindow(new InformeReservadoWindow(this.getParent(), this.getAsientoSeleccionado()));
			}
		} catch (NoPuedeReservarException e) {
			this.openWindow(new InformeErrorWindow(this.getParent(), "reserva", e.getMessage()));
		}
		this.buscar();
	}
	public void sobreReservarAsiento() {
		try {
			asientoSeleccionado.sobreReservar(AterrizarWindow.usuario);
			this.openWindow(new InformeExitosoWindow(this.getParent(), this.getAsientoSeleccionado(), "reservado"));
		} catch (NoPuedeReservarException e) {
			this.openWindow(new InformeErrorWindow(this.getParent(), "reserva", e.getMessage()));
		}
	}
	
	public void buscar(){
		this.validar();		
		Busqueda busquedaArealizar = new Busqueda(this.origen, this.destino, this.fecha);
		busquedaArealizar.setTipoUsuario(AterrizarWindow.usuario.getTipoUsuario());
		Collection<Vuelo> vuelos = TodasLasAerolineas.getInstance().buscarVuelos(busquedaArealizar);
		this.cargarAsientosDeVuelos(vuelos, busquedaArealizar);	}

	private Collection<Asiento> getReservasQueCumplen(Collection<Asiento> reservas, Busqueda busqueda) {
		ArrayList<Asiento> asientosQueCumplen = new ArrayList<Asiento>();
		for (Asiento asiento : reservas){
			if (asiento.getOrigen().equals(busqueda.getOrigen()) && asiento.getDestino().equals(busqueda.getDestino()) ){
				//TODO falta agregar la condicion de que las fechas sean iguales, para eso habria que parsear la fecha de la busqueda que esta en formato string
				asientosQueCumplen.add(asiento);
			}
		}
		return asientosQueCumplen;
	}


	protected void cargarAsientosDeVuelos(Collection<Vuelo> vuelos, Busqueda busqueda) {
		List<Asiento> nuevosResultados = new ArrayList<Asiento>();
		for (Vuelo vuelo : vuelos) {
			nuevosResultados.addAll(vuelo.getAsientos());
		}

		nuevosResultados.addAll(this.getReservasQueCumplen(AterrizarWindow.usuario.getReservas(), busqueda));

		this.setResultados(nuevosResultados);
	}


	protected void validar() {

		if (!this.ingresoDato(this.origen) || !this.ingresoDato(this.destino) || !this.ingresoDato(this.fecha) ) {
			throw new UserException("No puede haber campos vacios, revisar los valores ingresados.");
		}
//		try{
//			Flexible dateParserFleible = new Flexible();
//			dateParserFleible.convertir(this.fecha);	
//		}catch (ParseException pe ){
//			throw new UserException("Asegurese de ingresar un formato de fecha valido");
//		}
	}
	
	public boolean ingresoDato(String valor) {
		return valor != null && ! valor.trim().equals("");
	}

	public void limpiar() {
		this.origen = "";
		this.fecha = "";
		this.destino = "";
	}

	public String getOrigen() {
		return origen;
	}

	public void setOrigen(String origen) {
		this.origen = origen.toUpperCase();
		

	}

	public String getDestino() {
		return destino;
	}

	public void setDestino(String destino) {
		this.destino = destino.toUpperCase();
	}

	public String getFecha() {
		return fecha;
	}

	public void setFecha(String fecha) {

		this.fecha = fecha;
		
		if (!this.fecha.matches("^((0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/(19|20)\\d\\d)$")) {
			throw new UserException("La fecha debe estar en un formato dia/mes/año (Ej: 25/09/2012)");
		}
	}

	public List<Asiento> getResultados() {
		return resultados;
	}

	public void setResultados(List<Asiento> resultados) {
		this.resultados = resultados;
	}

	public Asiento getAsientoSeleccionado() {
		return asientoSeleccionado;
	}

	public void setAsientoSeleccionado(Asiento asientoSeleccionado) {
		this.asientoSeleccionado = asientoSeleccionado;
	}
	
	protected void openWindow(Window window) {
        window.open();
	}

	public void setParent(WindowOwner parent) {
		this.parent = parent;
	}

	public WindowOwner getParent() {
		return parent;
	}

	// ********************************************************
	// ** Accessors
	// ********************************************************

	
}
